package com.duke.payphone.buy;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Map;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import com.duke.payphone.Global;
import com.duke.payphone.LoginActivity;
import com.duke.payphone.R;
import com.duke.payphone.ServerPortal;
import com.duke.payphone.factory.MapFactory;


/**
 * displays info about the transaction
 * 
 * allows the buyer to select payment method, user must also enter pin to
 * confirm
 * 
 * when the buy presses Accept, app will send request with payment method to the
 * server to process
 * when server returns = "done" proceed to "BuyComplete"
 * (server will double check account credentials and pin #)
 * 
 * if server returns = "invalid", then toast = "pin invalid/transaction failed",
 * stay on this page
 * 
 * Buttons: Cancel, Accept
 * 
 * @author Michael
 * 
 */
public class BuyInfoActivity extends Activity {

    private Global globalvars;
    private Spinner cardSpinner;
    private ArrayAdapter<String> listAdapter;

    private TextView productname;
    private TextView date;
    private TextView price;
    private TextView seller;

    @Override
    public void onCreate (Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_buy_info);

        globalvars = (Global) getApplicationContext();
        cardSpinner = (Spinner) findViewById(R.id.sp_cards);

        productname = (TextView) findViewById(R.id.tv_productname);
        date = (TextView) findViewById(R.id.tv_date);
        price = (TextView) findViewById(R.id.tv_price);
        seller = (TextView) findViewById(R.id.tv_seller);

        // populate the text fields
        Intent i = getIntent();
        productname.setText(i.getExtras().getString("productname"));
        date.setText(i.getExtras().getString("date"));
        price.setText(i.getExtras().getString("price"));
        seller.setText(i.getExtras().getString("seller"));

        // populate the spinner with credit cards
        populateList();
    }

    @Override
    public boolean onCreateOptionsMenu (Menu menu) {
        // getMenuInflater().inflate(R.menu.activity_buy_info, menu);
        // return true;
        return false;
    }

    public void executeCancel (View v) {
        finish();
    }

    /**
     * @param v
     */
    public void executeBuy (View v) {

        if (true) {

            // send to server
            Map<String, Serializable> response = ServerPortal.contactServer(prepareTransmitMap());

            // wait for reply
            if (response.containsKey("server") && response.get("server").equals("valid")) {

                if (response.containsKey("session") && response.get("session").equals("valid")) {

                    if (response.containsKey("result") && response.get("result").equals("valid")) {
                        onBuyYesValid(response);
                    }
                    else {
                        onBuyYesInvalid(response);
                    }
                }
                else {
                    onSessionInvalid();
                }
            }
            else {
                onServerInvalid();
            }
        }
    }

    /**
     * returns a map
     * 
     * @return
     */
    private Map<String, Serializable> prepareTransmitMap () {

        // get credit card from spinner
        String cardid = String.valueOf(cardSpinner.getSelectedItem());

        // prepare the map
        Map<String, Serializable> request = MapFactory.createTransmitMap("buyyes");
        request.put("cardnumber", cardid);

        return request;
    }

    /**
     * @param response
     */
    private void onBuyYesValid (Map<String, Serializable> response) {

        Toast.makeText(globalvars, "Transaction confirmed.", Toast.LENGTH_SHORT).show();

        Intent toBuyComplete = new Intent(this, BuyCompleteActivity.class);

        if (response.containsKey("productname")) {
            toBuyComplete.putExtra("productname", (String) response.get("productname"));
        }
        if (response.containsKey("price")) {
            toBuyComplete.putExtra("price", (String) response.get("price"));
        }
        if (response.containsKey("date")) {
            toBuyComplete.putExtra("date", (String) response.get("date"));
        }
        if (response.containsKey("seller")) {
            toBuyComplete.putExtra("seller", (String) response.get("seller"));
        }
        if (response.containsKey("buyer")) {
            toBuyComplete.putExtra("buyer", (String) response.get("buyer"));
        }

        startActivity(toBuyComplete);
        finish();
    }

    /**
     * @param response
     */
    private void onBuyYesInvalid (Map<String, Serializable> response) {
        Toast.makeText(globalvars, "Unable to confirm transaction. Please try again.",
                       Toast.LENGTH_SHORT).show();
    }

    /**
     * populates the credit card list - runs on create
     * 
     * @param v
     */
    public void populateList () {

        Map<String, Serializable> request = MapFactory.createTransmitMap("cardlist");

        // check validity
        if (true) {

            // send to server
            Map<String, Serializable> response = ServerPortal.contactServer(request);

            // wait for reply
            if (response.containsKey("server") && response.get("server").equals("valid")) {

                if (response.containsKey("session") && response.get("session").equals("valid")) {

                    if (response.containsKey("result") && response.get("result").equals("valid")) {
                        onListValid(response);
                    }
                    else {
                        onListInvalid(response); // should not happen
                    }
                }
                else {
                    onSessionInvalid();
                }
            }
            else {
                onServerInvalid();
            }
        }

    }

    /**
     * load items from the credit card list
     * 
     * @param response
     */
    private void onListValid (Map<String, Serializable> response) {

        if (response.containsKey("cardlist")) {

            String[] cardArray = (String[]) response.get("cardlist");

            ArrayList<String> cardList = new ArrayList<String>();
            cardList.addAll(Arrays.asList(cardArray));

            // Create ArrayAdapter using the card list.
            listAdapter =
                    new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, cardList);

            // Set the ArrayAdapter as the ListView's adapter.
            listAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
            cardSpinner.setAdapter(listAdapter);

            Toast.makeText(globalvars, "Card list loaded.", Toast.LENGTH_SHORT).show();
        }
    }

    /**
     * Note: this should never happen
     * 
     * @param response
     */
    private void onListInvalid (Map<String, Serializable> response) {
        Toast.makeText(globalvars, "Card list load failed. Please try again.", Toast.LENGTH_SHORT)
                .show();
    }

    /**
     * If server has timed out
     */
    private void onServerInvalid () {
        // toast: server error, please verify server connection and retry
        Toast.makeText(globalvars, "Server/network error. Please retry.", Toast.LENGTH_SHORT)
                .show();
    }

    /**
     * If session has timed out
     */
    private void onSessionInvalid () {
        // reset the sessionID to null
        Global.sessionid = "";

        // toast: current session has timed out
        Toast.makeText(globalvars, "Current session has timed out.", Toast.LENGTH_SHORT).show();

        // go back to the login screen
        Intent toLogin = new Intent(this, LoginActivity.class);
        toLogin.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(toLogin);
        finish();
    }

}
